package cn.ciis.sys.role;

import cn.ciis.basic.base.BaseService;
import cn.ciis.basic.model.Permission;
import cn.ciis.basic.model.Role;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * 角色管理
 */
public class RoleAdminService extends BaseService {

    private Role dao = new Role().dao();

    @Override
    public Model getDao() {
        return dao;
    }

    public Page<Role> paginate(int pageNum, int pageSize) {
        return dao.paginate(pageNum, pageSize, "select *", "from sys_role order by id desc");
    }

    public Role findById(int roleId) {
        return dao.findById(roleId);
    }

    public List<Role> getAllRoles(boolean b) {
        return dao.find("select * from sys_role " + (b ? "" : "where id<>1") + " order by id asc");
    }

    /**
     * 判断角色名是否存在
     *
     * @param roleId 当前 role 对象的 id 号，如果 role 对象还未创建，提供一个小于 0 的值即可
     * @param name   角色名
     */
    public boolean exists(int roleId, String name) {
        name = name.toLowerCase().trim();
        String sql = "select id from sys_role where lower(name) = ? and id != ? limit 1";
        Integer id = Db.queryInt(sql, name, roleId);
        return id != null;
    }

    /**
     * 创建角色
     */
    public Ret save(Role role) {
        if (exists(-1, role.getName())) {
            return Ret.fail("msg", "角色名称已经存在，请输入别的名称");
        }

        role.setName(role.getName().trim());
        role.setCreateAt(new Date());
        role.save();
        return Ret.ok("msg", "创建成功");
    }

    /**
     * 更新角色
     */
    public Ret update(Role role) {
        if (exists(role.getId(), role.getName())) {
            return Ret.fail("msg", "角色名称已经存在，请输入别的名称");
        }

        role.setName(role.getName().trim());
        role.update();
        return Ret.ok("msg", "角色更新成功");
    }

    @Override
    public Ret delete(final int roleId) {
        if (roleId == 1) {
            return Ret.fail("msg", "id 值为 1 的超级管理员不能被删除");
        }

        Db.tx(
                () -> {
                    Db.delete("delete from sys_account_role where roleId=?", roleId);
                    Db.delete("delete from sys_role_permission where roleId=?", roleId);
                    dao.deleteById(roleId);
                    return true;
                });

        return Ret.ok("msg", "角色删除成功");
    }

    /**
     * 添加权限
     */
    public Ret addPermission(int roleId, String permissionId) {
        if (roleId == 1) {
            return Ret.fail("msg", "超级管理员天然拥有所有权限，无需分配");
        }
        Record record = null;
        String[] split = permissionId.split(",");

        for (int i = 0; i < split.length; i++) {
            Record first =
                    Db.findFirst(
                            "select * from sys_role_permission where roleId=? and permissionId=?",
                            roleId,
                            split[i]);
            if (null == first) {
                record = new Record().set("roleId", roleId).set("permissionId", split[i]);
                Db.save("sys_role_permission", record);
            } else {
                continue;
            }
        }
        return Ret.ok("msg", "添加权限成功");
    }

    /**
     * 删除权限
     */
    public Ret deletePermission(int roleId, String permissionId) {
        if (roleId == 1) {
            return Ret.fail("msg", "超级管理员天然拥有所有权限，不能删除权限");
        }
        String[] split = permissionId.split(",");
        for (int i = 0; i < split.length; i++) {
            Db.delete(
                    "delete from sys_role_permission where roleId=? and permissionId=?", roleId, split[i]);
        }
        return Ret.ok("msg", "删除权限成功");
    }

    /**
     * 标记出 role 拥有的权限，用于在界面输出 checkbox 的 checked 属性 未来用 permission left join role_permission 来优化
     */
    public void markAssignedPermissions(Role role, List<Permission> permissionList) {
        // id 为 1 的超级管理员默认拥有所有权限
        if (role.getId() == 1) {
            for (Permission permission : permissionList) {
                permission.put("assigned", true);
            }
            return;
        }

        String sql = "select roleId from sys_role_permission where roleId=? and permissionId=? limit 1";
        for (Permission permission : permissionList) {
            Integer roleId = Db.queryInt(sql, role.getId(), permission.getId());
            if (roleId != null) {
                // 设置 assigned 用于界面输出 checked
                permission.put("assigned", true);
            }
        }
    }

    /**
     * 根据 controller 将 permission 进行分组
     */
    public LinkedHashMap<String, List<Permission>> groupByController(
            List<Permission> permissionList) {
        LinkedHashMap<String, List<Permission>> ret =
                new LinkedHashMap<String, List<Permission>>();

        for (Permission permission : permissionList) {
            String controller = permission.getController();
            List<Permission> list = ret.get(controller);
            if (list == null) {
                list = new ArrayList<Permission>();
                ret.put(controller, list);
            }

            list.add(permission);
        }

        return ret;
    }


    /**
     * 查询所有action的备注
     *
     * @return
     */
    public List<Record> listActionNotes(String mode) {
        String sql =
                "select * from(select (@i:=@i+1) id,actionKey,notes,identification from sys_action_notes,(select @i:=0)j ORDER BY actionKey)a";
        if (null != mode) {
            sql += " where id in(" + mode + ")";
        }
        return Db.find(sql);
    }

    /**
     * 查询传入账号的角色列表
     * @param account
     * @return
     */
    public List<Role> findMyRoles(int account){
        SqlPara sqlPara = getDao().getSqlPara("sys_role.findMyRoles");
        return dao.find(sqlPara.getSql(), account);
    }
}
